using System.Net.Sockets;
using System.Net;
using System.Collections.Concurrent;
using Google.Protobuf;
using muduoDotNet.Common;

namespace muduoDotNet
{
    /// <summary>
    /// TcpServer类，服务器端的核心组件
    /// </summary>
    public class TcpServer : IDisposable
    {
        private readonly EventLoop _loop;
        private readonly IPEndPoint _listenAddr;
        private readonly Socket _acceptSocket;
        private readonly Channel _acceptChannel;
        private readonly ConcurrentDictionary<string, TcpConnection> _connections;
        private int _nextConnId;
        private bool _started;
        private bool _disposed;
        
        // 新增模块
        private ConnectionPool _connectionPool;
        private RecoveryManager _recoveryManager;
        private Configuration _configuration;
        
        // 协议编解码相关
        private IProtocolCodec? _protocolCodec;
        private IProtocolMessageHandler? _messageHandler;

        public TcpServer(EventLoop loop, IPEndPoint listenAddr)
        {
            _loop = loop ?? throw new ArgumentNullException(nameof(loop));
            _listenAddr = listenAddr ?? throw new ArgumentNullException(nameof(listenAddr));
            _acceptSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _acceptChannel = new Channel(loop, _acceptSocket.Handle.ToInt32());
            _connections = new ConcurrentDictionary<string, TcpConnection>();
            _nextConnId = 1;
            _started = false;
            _disposed = false;
            
            // 初始化配置管理器
            _configuration = Configuration.GetInstance();
            
            // 初始化连接池（如果启用）
            if (_configuration.GetValue<bool>("performance.connection.pool.enabled", false))
            {
                var minPoolSize = _configuration.GetValue<int>("performance.connection.pool.min", 5);
                var maxPoolSize = _configuration.GetValue<int>("performance.connection.pool.max", 100);
                _connectionPool = new ConnectionPool(loop, listenAddr, minPoolSize, maxPoolSize);
            }
            
            // 初始化恢复管理器（如果启用）
            if (_configuration.GetValue<bool>("network.recovery.enabled", false))
            {
                var maxReconnectAttempts = _configuration.GetValue<int>("network.reconnect.attempts", 5);
                var reconnectIntervalMs = _configuration.GetValue<int>("network.reconnect.interval.ms", 5000);
                _recoveryManager = new RecoveryManager(maxReconnectAttempts, reconnectIntervalMs);
            }
            
            // 初始化协议支持
            _protocolCodec = new ProtobufCodec(); // 默认使用protobuf编解码器

            // 注册Socket到管理器
            SocketManager.RegisterSocket(_acceptSocket);

            // 设置Socket选项
            _acceptSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            _acceptSocket.Bind(_listenAddr);

            // 设置Channel的读回调为AcceptConnection
            _acceptChannel.ReadCallback = AcceptConnection;
        }

        public TcpServer(EventLoop loop, string ip, int port)
            : this(loop, new IPEndPoint(IPAddress.Parse(ip), port))
        { }

        public EventLoop Loop => _loop;
        public IPEndPoint ListenAddr => _listenAddr;
        public int ConnectionCount => _connections.Count;
        
        // 新增属性
        public ConnectionPool ConnectionPool => _connectionPool;
        public RecoveryManager RecoveryManager => _recoveryManager;
        public Configuration Configuration => _configuration;
        
        // 协议相关属性
        public IProtocolCodec? ProtocolCodec
        {
            get => _protocolCodec;
            set => _protocolCodec = value;
        }
        
        public IProtocolMessageHandler? MessageHandler
        {
            get => _messageHandler;
            set => _messageHandler = value;
        }

        // 事件回调
        public Action<TcpConnection> ConnectionCallback { get; set; }
        public Action<TcpConnection, Buffer> MessageCallback { get; set; }
        public Action<TcpConnection> WriteCompleteCallback { get; set; }

        /// <summary>
        /// 启动服务器
        /// </summary>
        public void Start()
        {
            if (!_started)
            {
                _started = true;
                
                // 增加活跃连接计数
                PerformanceCounters.IncrementActiveConnections();
                
                // 开始监听连接
                _acceptSocket.Listen(1024);
                
                // 启用接受连接的Channel
                _acceptChannel.EnableReading();
            }
        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        public void Stop()
        {
            if (_started)
            {
                _started = false;
                
                // 减少活跃连接计数
                PerformanceCounters.DecrementActiveConnections();
                
                // 禁用接受连接的Channel
                _acceptChannel.DisableReading();
                
                // 关闭所有连接
                var conns = _connections.Values.ToList();
                foreach (var conn in conns)
                {
                    conn.Shutdown();
                }
            }
        }

        /// <summary>
        /// 接受新连接
        /// </summary>
        private void AcceptConnection()
        {
            _loop.AssertInLoopThread();
            
            try
            {
                // 接受新的连接
                var connectedSocket = _acceptSocket.Accept();
                if (connectedSocket != null)
                {
                    // 记录连接建立
                    PerformanceCounters.IncrementTotalConnections();
                    
                    // 创建新的TcpConnection对象
                    var connName = $"connection_{_nextConnId++}";
                    var connection = new TcpConnection(_loop, connName, connectedSocket);
                    
                    // 设置协议编解码器
                    if (_protocolCodec != null)
                    {
                        connection.ProtocolCodec = _protocolCodec;
                    }
                    if (_messageHandler != null)
                    {
                        connection.MessageHandler = _messageHandler;
                    }
                    
                    // 设置回调
                    connection.ConnectionCallback = ConnectionCallback;
                    connection.MessageCallback = MessageCallback;
                    connection.WriteCompleteCallback = WriteCompleteCallback;
                    connection.CloseCallback = RemoveConnection;
                    
                    // 如果启用了恢复管理，注册连接
                    if (_recoveryManager != null)
                    {
                        _recoveryManager.RegisterConnection(connection, ReconnectHandler);
                    }
                    
                    // 注册到连接列表
                    _connections.TryAdd(connName, connection);
                    
                    // 建立连接
                    connection.ConnectEstablished();
                }
            }
            catch (SocketException ex)
            {
                // 记录连接失败
                PerformanceCounters.IncrementFailedConnections();
                PerformanceCounters.IncrementNetworkExceptions();
                
                // 处理非阻塞Socket的EWOULDBLOCK错误
                if (ex.SocketErrorCode == SocketError.WouldBlock ||
                    ex.SocketErrorCode == SocketError.IOPending ||
                    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
                {
                    // 这些错误是预期的，继续处理
                }
                else
                {
                    Logger.Error($"Socket accept error: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 重连处理函数
        /// </summary>
        /// <param name="connection">TCP连接</param>
        /// <returns>是否重连成功</returns>
        private bool ReconnectHandler(TcpConnection connection)
        {
            try
            {
                // 这里实现重连逻辑
                // 对于服务器端，通常不需要主动重连客户端
                // 但对于某些场景（如反向连接），可能需要实现
                Logger.Info($"Reconnect handler called for connection: {connection.Name}");
                return true;
            }
            catch (Exception ex)
            {
                Logger.Error($"Reconnect handler error: {ex.Message}", ex);
                return false;
            }
        }

        /// <summary>
        /// 移除连接
        /// </summary>
        /// <param name="conn">要移除的连接</param>
        private void RemoveConnection(TcpConnection conn)
        {
            _loop.RunInLoop(() => RemoveConnectionInLoop(conn));
        }

        /// <summary>
        /// 在事件循环线程中移除连接
        /// </summary>
        /// <param name="conn">要移除的连接</param>
        private void RemoveConnectionInLoop(TcpConnection conn)
        {
            _loop.AssertInLoopThread();
            
            // 从连接列表中移除
            if (_connections.TryRemove(conn.Name, out _))
            {
                // 减少活跃连接计数
                PerformanceCounters.DecrementActiveConnections();
                
                // 销毁连接
                conn.ConnectDestroyed();
            }
        }

        /// <summary>
        /// 向所有连接发送数据
        /// </summary>
        /// <param name="message">要发送的数据</param>
        public void SendToAll(byte[] message)
        {
            foreach (var conn in _connections.Values)
            {
                conn.Send(message);
            }
        }

        /// <summary>
        /// 向所有连接发送protobuf消息
        /// </summary>
        /// <param name="message">要发送的protobuf消息</param>
        public void SendProtobufMessageToAll(IMessage message)
        {
            foreach (var conn in _connections.Values)
            {
                conn.SendProtobufMessage(message);
            }
        }

        /// <summary>
        /// 获取指定名称的连接
        /// </summary>
        /// <param name="name">连接名称</param>
        /// <returns>连接对象，如果不存在返回null</returns>
        public TcpConnection? GetConnection(string name)
        {
            _connections.TryGetValue(name, out var connection);
            return connection;
        }

        public void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                
                // 停止服务器
                Stop();
                
                // 释放连接池
                _connectionPool?.Dispose();
                
                // 释放恢复管理器
                _recoveryManager?.Dispose();
                
                try
                {
                    // 取消注册Socket
                    SocketManager.UnregisterSocket(_acceptSocket);
                    _acceptSocket.Close();
                }
                catch (Exception ex)
                {
                    Logger.Error($"Listen socket close error: {ex.Message}");
                }
                
                _acceptChannel.Dispose();
            }
        }
    }
}